﻿using Swift.Math;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Swift;
using SCM;

/// <summary>
/// 播放模型动画
/// </summary>
public class AnimationPlayer : MonoBehaviour
{
    public UnitCreator UC;

    Animator animator;
    MapUnit mu;

    const int idle = 0;
    const int attack01 = 1;
    const int attack02 = 2;
    const int moving = 3;
    const int die = 4;
    const int constructingUnit = 5;
    const int constructingPhrase1 = 6;
    const int constructingPhrase2 = 7;
    const int inBuilding = 8;

    Transform headTrans = null;
    AnimationPlayer headAni = null;

    void Awake()
    {
        animator = GetComponentInChildren<Animator>();
        mu = GetComponent<MapUnit>();

        headTrans = mu == null || mu.Root == null ? null : mu.Root.Find("Head");
        headAni = headTrans == null ? null : headTrans.GetComponent<AnimationPlayer>();
    }

    private void Update()
    {
        if (mu == null || mu.U == null || mu.U.cfg.MaxVelocity == 0)
            return;

        var st = mu.U.Room == null ? "die" : mu.U.Room.GetSM(mu.U).CurrentState;
        if (st == "idle" || st == "guarding")
            Idle();
        else if (st == "moving" || st == "chasing")
            Move();
    }

    public void Idle()
    {
        if (animator != null)
            animator.SetInteger("state", idle);
    }

    public void Die()
    {
        if (animator != null)
            animator.SetInteger("state", die);

        if (headAni != null)
            headAni.Die();

        if (scaffold != null)
        {
            Destroy(scaffold.gameObject);
            scaffold = null;
            scaffoldUID = null;
        }
    }

    string scaffoldUID = null;
    MapUnit scaffold = null;
    void CreateScaffold()
    {
        if (scaffold != null)
            return;

        var mu = GetComponent<MapUnit>();
        scaffoldUID = mu.U.UID + "_Scaffold";
        scaffold = UC.CreateModel("Scaffold", scaffoldUID, 0, false, false, false);
        UC.UnhandleModel(scaffoldUID); // 脚手架模型是动画的一部分，交给动画自己管理
        scaffold.transform.SetParent(transform, false);
        scaffold.transform.localPosition = Vector3.zero;
        scaffold.transform.localScale = Vector3.one;
        scaffold.transform.localRotation = Quaternion.identity;
        scaffold.gameObject.SetActive(true);
    }

    public void Construcing(float totalTime)
    {
        if (mu.U.cfg.IsAccessory)
            animator.SetInteger("state", inBuilding);
        else
        {
            CreateScaffold();
            transform.Find("Root").gameObject.SetActive(false);
            var sfAni = scaffold.GetComponent<AnimationPlayer>();
            sfAni.ConstructingPhrase1();
            StartCoroutine(DelayRun(totalTime / 2, () =>
            {
                transform.Find("Root").gameObject.SetActive(true);
                sfAni.ConstructingPhrase2();
            }));
        }
    }

    public void ConstructingComplete()
    {
        if (mu.U.cfg.IsAccessory)
            animator.SetInteger("state", idle);
        else
        {
            transform.Find("Root").gameObject.SetActive(true);
            Destroy(scaffold.gameObject);
            scaffold = null;
            scaffoldUID = null;

            // 主基地上级上来的，要增加一个头部部件
            var type = mu.U.UnitType;
            if (mu.U.cfg.LevelUpFrom == "CommanderCenter")
            {
                var head = transform.Find("Root/" + type);
                head.gameObject.SetActive(true);
                headTrans = head;
                headAni = headTrans.GetComponent<AnimationPlayer>();
            }
        }
    }

    IEnumerator DelayRun(float waitingTime, Action fun)
    {
        yield return new WaitForSeconds(waitingTime);
        fun();
    }

    public void LevelUpConstructing(float totalTime)
    {
        CreateScaffold();
        scaffold.GetComponent<AnimationPlayer>().ConstructingPhrase2();
        animator.SetInteger("state", inBuilding);
    }

    void ConstructingPhrase1()
    {
        if (animator != null)
            animator.SetInteger("state", constructingPhrase1);
    }

    void ConstructingPhrase2()
    {
        if (animator != null)
            animator.SetInteger("state", constructingPhrase2);
    }

    public void ConstructingUnit()
    {
        if (animator != null)
            animator.SetInteger("state", constructingUnit);
    }

    public void ConstructingUnitComplete()
    {
        if (animator != null)
            animator.SetInteger("state", idle);
    }

    public void Move()
    {
        if (animator != null)
            animator.SetInteger("state", moving);
    }

    public void AttackGround(Fix64 attackDir, Vec2 targetPos)
    {
        if (animator != null)
            animator.SetInteger("state", attack01);

        if (headTrans == null)
            transform.rotation = Quaternion.Euler(0, -(float)attackDir, 0);

        if (headAni != null)
            headAni.AttackGround(attackDir, targetPos);
    }

    public void AttackAir(Fix64 attackDir, Vec2 targetPos)
    {
        if (animator != null)
            animator.SetInteger("state", attack02);

        if (headTrans == null)
            transform.rotation = Quaternion.Euler(0, -(float)attackDir, 0);

        if (headAni != null)
            headAni.AttackAir(attackDir, targetPos);
    }
}
